package service

import (
	"errors"
	"github.com/bgmp/config"
	"github.com/bgmp/model"
	"github.com/robfig/cron/v3"
	log "github.com/sirupsen/logrus"
	"sort"
	"time"
)

func InitCron() {
	c := cron.New()
	_, err := c.AddFunc("@every 15m", func() {
		log.Debug("尝试进行一轮更新")
		ids, err := model.GetUserIds(config.DB)
		if err == nil {
			for _, id := range ids {
				TrySavePredict(id, model.Time{Time: time.Now()})
				log.Debugf("更新 %d 信息", id)
			}
		}
	})
	if err != nil {
		return
	}
	log.Debug("开始每15分钟执行预测定时任务")
	c.Run()
}

func GetBgs(userId uint, t model.Time, total int) ([]model.Bg, error) {
	delta := time.Duration(total) * -15 * time.Minute

	bgs := model.ListBgs(config.DB,
		map[string]any{model.Bg_UserId: userId},
		&model.BgSelectConditions{
			Start: model.Time{
				Time: t.Time.Add(delta),
			},
			End:  t,
			Type: model.BgNull,
		})
	delta = -15 * time.Minute
	sort.Slice(bgs, func(i, j int) bool {
		return bgs[i].Time.After(bgs[j].Time)
	})
	var result []model.Bg
	//sum := 0
	length := len(bgs)
	t.Time = t.Time.Add(delta)

	for i := 0; i < length; {
		has := false
		for {
			if bgs[i].Time.After(t.Time) {
				has = true
				result = append(result, bgs[i])
				i++
				if i >= length {
					break
				}
			} else {
				break
			}
		}
		t.Time = t.Time.Add(delta)
		if !has {
			// 插入一个预测数据
			predicts, err := model.GetPredictDataBetween(config.DB, userId, t.Time, t.Time.Add(-1*delta))
			if err == nil {
				for _, predict := range predicts {
					result = append(result, predict.ToBg())
				}
			}
		}
		if len(result) >= total {
			break
		}
	}
	if len(result) < total {
		return nil, errors.New("not enough")
	}

	return result, nil
}

func TrySavePredict(userId uint, t model.Time) {
	//bgs := model.GetBgBefore(config.DB, userId, t, 96)
	bgs, err := GetBgs(userId, t, 96)
	if err != nil {
		log.Error(err)
		return
	}
	//if len(bgs) < 96 {
	//	return
	//}
	//tmpTime := bgs[0].Time
	//upTime := 33 * time.Minute
	//for _, bg := range bgs {
	//	tmp2 := bg.Time
	//	diff := -1 * tmp2.Sub(tmpTime)
	//	if diff > upTime {
	//		return
	//	}
	//	tmpTime = tmp2
	//}
	result := BgPredict(bgs)
	if result == nil {
		log.Error("获取预测结果失败")
		return
	}
	predict := model.PredictData{
		UserId:    userId,
		Value:     result[0].Value,
		PredictAt: time.Unix(result[0].Time, 0),
	}
	if predict.Value > 50 {
		predict.Value /= MG_L_TO_MMOL_L
	}
	log.Debug("保存数据 ", predict)
	err = predict.Create(config.DB)
	if err != nil {
		log.Error(err.Error())
		return
	}
}
